package net.yussi.component.chart.pie3D
{
    import mx.collections.ArrayCollection;
    import mx.core.UIComponent;

    public class PieChart3D extends UIComponent
    {
        private var pie:PieDrawer;	

        private var _data:ArrayCollection; //차트데이터
        private var _xRadius:Number = 100; //X축 반지름
        private var _yRadius:Number = 100; //Y축 반지름
        private var _pieDepth:Number = 30; //파이부피
		
		private var _rotationAngle:Number = 150;//파이 앵글  2010.05.20 추가

        public function PieChart3D()
        {
            super();
        }
		
		/**
		 * 
		 * ArrayCollection의 오브젝트 형식 {data:100,color:0xFFF600,displayName:"test1"}
		 * @param value 차트데이터
		 * 				
		 */		
        public function set data(value:ArrayCollection):void
        {
            this._data = value;
			
			if (this._data.length < 1)
				return;
			
            makePie();
        }
		
		/**
		 * 
		 * @param value 차트데이터
		 * 
		 */	
        public function get data():ArrayCollection
        {
            return _data;
        }
		
		/**
		 * 
		 * @param value 파이의 깊이
		 *  
		 */		
        public function set pieDepth(value:Number):void
        {
            _pieDepth = value;
        }
		
		/**
		 *
		 * y축 반지름 
		 * @return 
		 * 
		 */			
        public function get yRadius():Number
        {
            return _yRadius;
        }
		
		/**
		 * 
		 * @return y축 반지름
		 * 
		 */
        public function set yRadius(value:Number):void
        {
            _yRadius = value;
        }
		
		/**
		 * 
		 * @return x축 반지름
		 * 
		 */
        public function get xRadius():Number
        {
            return _xRadius;
        }
		/**
		 * 
		 * x축 반지름
		 * @param value
		 * 
		 */
        public function set xRadius(value:Number):void
        {
            _xRadius = value;
        }
		
		/**
		 * 
		 * @return 
		 * 
		 */		
		public function get rotationAngle():Number
		{
			return _rotationAngle;
		}
		
		/**
		 * 
		 * 파이의 회전 각도
		 * @param value 파이의 회전 각도
		 * 
		 */		
		public function set rotationAngle(value:Number):void
		{
			_rotationAngle = value;
		}
		
		/**
		 * 파이차트 데이터 가공
		 * 
		 */		
        private function makePie():void
        {
            var cnt:Number;
            var len:Number = data.length;
            var tempTotalSum:Number = 0;
            for (cnt = 0; cnt < len; cnt++)
            {
                tempTotalSum += data[cnt].data;
            }

            var toData:Array = new Array(); //pie데이터
            var endAngle:Number = 0; //끝각
            var startAngle:Number = 0; //시작각
            for (cnt = 0; cnt < len; cnt++)
            {
                var tempPieUintPer:Number = Math.round(((data[cnt].data * 100) / tempTotalSum) * 100) / 100; //퍼센트
                endAngle = (tempPieUintPer * 3.6) + endAngle; //끝각
                var toDataUnit:Object = pieUnitDataObject(startAngle, endAngle, _xRadius, _yRadius, _pieDepth, data[cnt].color, 0, data[cnt].displayName);
                toData.push(toDataUnit);
                startAngle = endAngle;
            }
			
			if(pie != null)
			{
				while (pie.numChildren > 0)
				{
					pie.removeChildAt(0);
				}
			}

            pie = new PieDrawer();
            pie.setData(toData, 0, 1.4, 30);
            this.addChild(pie);
        }

        /**
		 * 
         * 16진수 색상을 다시 0–255 범위의 10진수 숫자 네 개(각 숫자는 ARGB 채널 각각을 나타냄)로 변환
         * @param colorCode 16진수컬러코드  
		 * 					ex) 0xffffff -> rgb(255, 255, 255)형식으로 분리 red,green,blue 
		 * 
         */
        private function hexToRgb(colorCode:Number):Object
        {
            var color:Object = {};
            //color.alpha = (colorCode >> 24) & 0xFF
            color.red = (colorCode >> 16) & 0xFF
            color.green = (colorCode >> 8) & 0xFF
            color.blue = colorCode & 0xFF
            return color;
        }
		
		/**
		 * 
		 * 파이조각의 데이터 오브젝트를 만들어서 리턴
		 * @param startAngle 시작각
		 * @param endAngle 끝각
		 * @param xRadius x축 반지름
		 * @param yRadius y축 반지름
		 * @param depth 깊이
		 * @param color 색상
		 * @param fromCenter ?
		 * @param displayName 디스플레이네임
		 * @return 
		 * 
		 */		
        private function pieUnitDataObject(startAngle:Number, 
            endAngle:Number, 
            xRadius:Number, 
            yRadius:Number, 
            depth:Number, 
            color:uint,
            fromCenter:Number,
			displayName:String = ""):Object
        {
			
            /**
             * 0x00000 -> RGB(255,255,255)형식으로 변경
             */
            var colorCode:Object = hexToRgb(color);
            var redCode:int = colorCode.red;
            var greenCode:int = colorCode.green;
            var blueCode:int = colorCode.blue;

            var obj:Object = new Object();
			obj.startAngle = startAngle; //시작각
			obj.endAngle = endAngle; //끝각
			obj.xRadius = xRadius; //X축반지름
			obj.yRadius = yRadius; //Y축반지름 
			obj.depth = depth; //깊이
			obj.colorTop = getGradientColor(redCode, greenCode, blueCode);
			obj.colorSide1 = getGradientColor(redCode / 1.8, greenCode / 1.8, blueCode / 1.8);
			obj.colorSide2 = getGradientColor(redCode / 1.6, greenCode / 1.6, blueCode / 1.6);
			obj.colorSide3 = getGradientColor(redCode / 1.4, greenCode / 1.4, blueCode / 1.4);
			obj.fromCenter = 0; //?
			obj.toFromCenter = fromCenter; //?
			obj.subject = ": " + displayName; // 디스플레이 이름
            return obj;
        }
		
		/**
		 * 
		 * rgb(255,255,255)색상으로 3가지 그라이언트색상을 만들어 배열으로 리턴
		 * @param red 10진수 빨간색
		 * @param green 10진수 녹색
		 * @param blue 10진수 파란색
		 * @return 
		 * 
		 */		
        private function getGradientColor(red:Number = 255, green:Number = 255, blue:Number = 255):Array
        {
            var colorArr:Array = new Array();
			colorArr.push(rgbToHex(red + (255 - red) / 3, green + (255 - green) / 3, blue + (255 - blue) / 3));
			colorArr.push(rgbToHex(red, green, blue));
			colorArr.push(rgbToHex(red / 2, green / 2, blue / 2));
            return colorArr;
        }
		
		/**
		 * 
		 * rgb형식의 컬러코드를 -> 0x000000형식의 컬러코드로 변경
		 * @param r red
		 * @param g green
		 * @param b blue
		 * @return uint ex) 0x000000
		 * 
		 */		
        private function rgbToHex(r:int,g:int,b:int):uint
        {
            var ret:uint = uint("0x" + decToHex(r) + decToHex(g) + decToHex(b));
            return ret;
        }

		/**
		 * 
		 * 10진수 -> 16진수 변화
		 * @param dec 10진수
		 * @return 16진수
		 *
		 */		
        private function decToHex(dec:int):String
        {
            var hex:String = dec.toString(16);
            if (hex.length < 2)
            {
                return "0" + hex;
            }
            return hex;
        }
		
        override protected function createChildren():void
        {
            super.createChildren();

            if (pie == null)
                pie = new PieDrawer();

            //중심으로 이동
            pie.x = this.width / 2;
            pie.y = this.height / 2;
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            //중심으로 이동
            if (pie == null)
                return;
            pie.x = this.width / 2;
            pie.y = this.height / 2;
        }
    }
}